<!--
 * @Autor: dingxiaolin
 * @Date: 2021-08-28 23:49:10
 * @LastEditors: dingxiaolin
 * @LastEditTime: 2021-09-16 17:00:59
-->
<template>
    <div id="container">
        <div id="panel"></div>
    </div>
    <div class="input-card" style="width: auto">
        <div class="input-item">
            <button class="btn" @click="defaultLayer">默认图层</button>
        </div>
        <div class="input-item">
            <button class="btn" @click="haituLayer">海事图层</button>
        </div>
        <div class="input-item">
            <button class="btn" @click="imageLayer">影像图层</button>
        </div>
    </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs, ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from '@/store'
import { message } from 'ant-design-vue'
import gcoord from 'gcoord'
import { throttle, debounce } from 'lodash'
import axios from 'axios'
import { base64encode } from './base64'
export default defineComponent({
    name: 'index',
    components: {},
    props: {},
    emits: [],
    setup(props, ctx) {
        const router = useRouter()
        const store = useStore()
        const map = ref()
        const timer = ref()
        const time = 4000 // 船舶数据获取间隔
        /**信息窗体 */
        const infoWindow = new AMap.InfoWindow({
            isCustom: false,
            closeWhenClickMap: true,
            showShadow: false,
            offset: new AMap.Pixel(0, -20)
        })
        /**圆形标注 */
        const circleMarker = new AMap.CircleMarker({
            radius: 15, //3D视图下，CircleMarker半径不要超过64px
            strokeColor: 'red',
            strokeWeight: 2,
            strokeOpacity: 0.5,
            // fillColor: 'rgba(255,255,0,1)',
            fillOpacity: 0.5,
            zIndex: 15,
            cursor: 'pointer',
            clickable: true
        })

        // const key = 'ce6efc528c9890f66eb7b5dce8b78d5b' //天地图的key
        const key = '0410b18a399adb3997ebb32215fdff84' //dxl天地图的key
        /**批量标注图层 */
        const textlayer = new AMap.LabelsLayer({
            zooms: [14, 18],
            // zIndex: 1001,
            // 开启标注避让，默认为开启，v1.4.15 新增属性
            collision: true,
            // 开启标注淡入动画，默认为开启，v1.4.15 新增属性
            animation: true
        })
        const state = reactive({
            /**天地图底图 */
            xyzTileLayer: new AMap.TileLayer({
                getTileUrl: `http://t{0,1,2,3,4,5,6,7}.tianditu.gov.cn/DataServer?T=vec_w&tk=${key}&x=[x]&y=[y]&l=[z]`,
                zIndex: 1
            }),
            /**天地图文字标注图 */
            wordTileLayer: new AMap.TileLayer({
                getTileUrl: `http://t{0,1,2,3,4,5,6,7}.tianditu.gov.cn/DataServer?T=cva_w&tk=${key}&x=[x]&y=[y]&l=[z]`,
                zIndex: 2
            }),
            /**天地图网路图 */
            roadTileLayer: new AMap.TileLayer({
                getTileUrl: `http://t{0,1,2,3,4,5,6,7}.tianditu.gov.cn/DataServer?T=cia_w&tk=${key}&x=[x]&y=[y]&l=[z]`,
                zIndex: 3
            }),
            /**天地图卫星图 */
            sateTileLayer: new AMap.TileLayer({
                getTileUrl: `http://t{0,1,2,3,4,5,6,7}.tianditu.gov.cn/DataServer?T=img_w&tk=${key}&x=[x]&y=[y]&l=[z]`,
                zIndex: 1
            }),
            /**纯长江航道图 */
            cjTileUrl: new AMap.TileLayer.WMS({
                url: 'http://geo.jinhx.cn:8089/geoserver/gwc/service/wms',
                tileSize: 256,
                zIndex: 3,
                params: {
                    SERVICE: 'WMS',
                    FORMAT: 'image/png',
                    VERSION: '1.1.1',
                    request: 'GetMap',
                    tiled: true,
                    SRS: 'EPSG:3857',
                    LAYERS: 'marinfo:hq'
                }
            }),
            /**海事图 */
            seaLayer: new AMap.TileLayer({
                getTileUrl: function (x, y, z) {
                    var imgurl = '/ALL/' + z + '/' + x + '/' + y + '.png'
                    return imgurl
                },
                zIndex: 1
            }),
            /**覆盖物群组 */
            overlayGroup: new AMap.OverlayGroup(),
            /**船舶标注 */
            shipMarkers: [] as any,
            /**当前船舶数据 */
            curData: [] as any,
            /**当前船舶样式 */
            curStyle: [] as any,
            MassMarksLayer: new AMap.MassMarks([], {
                zIndex: 1000,
                anchor: new AMap.Pixel(6, 6),
                size: new AMap.Size(12, 20)
            })
        })
        onMounted(() => {
            // 创建地图实例
            const options = {
                resizeEnable: true,
                viewMode: '2D', //开启3D视图,默认为关闭
                expandZoomRange: false,
                zoom: 14,
                zooms: [3, 18],
                layers: [state.cjTileUrl, state.xyzTileLayer, state.wordTileLayer], //常规图
                center: [120.945421, 31.792806]
            }
            map.value = new AMap.Map('container', options)

            //经纬度转换测试
            var result = gcoord.transform(
                [119.502844, 32.204492], // 经纬度坐标
                gcoord.GCJ02, // 当前坐标系
                gcoord.WGS84 // 目标坐标系
            )
            console.log('result', result, map.value.getBounds().southwest)

            circleMarker.setMap(map.value)
            circleMarker.on('mouseout', showInfoOut)
            // drawPolygon()
            // 加载海事资源图层
            otherLayer()
            // 加载控件
            addController()
            // 加载事件
            mapEvent()
            // 加载船舶展示
            showShips()
        })

        onUnmounted(() => {
            console.log('ttttttttttttttttttt')
            clearInterval(timer.value)
        })

        function defaultLayer() {
            var clearGroup = new AMap.LayerGroup([state.sateTileLayer, state.roadTileLayer, state.seaLayer])
            clearGroup.setMap(null)
            var layerGroup = new AMap.LayerGroup([state.cjTileUrl, state.xyzTileLayer, state.wordTileLayer])
            layerGroup.setMap(map.value)
        }
        function haituLayer() {
            var clearGroup = new AMap.LayerGroup([state.cjTileUrl, state.xyzTileLayer, state.wordTileLayer, state.roadTileLayer, state.sateTileLayer])
            clearGroup.setMap(null)
            state.seaLayer.setMap(map.value)
        }
        function imageLayer() {
            var clearGroup = new AMap.LayerGroup([state.cjTileUrl, state.xyzTileLayer, state.wordTileLayer, state.seaLayer])
            clearGroup.setMap(null)
            var layerGroup = new AMap.LayerGroup([state.sateTileLayer, state.roadTileLayer])
            layerGroup.setMap(map.value)
        }
        /**海事资源图层 */
        function otherLayer() {
            //码头
            axios(
                'http://geo.jinhx.cn:8089/geoserver/marinfo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=marinfo:elec_range_port&maxFeatures=50&outputFormat=application%2Fjson'
            ).then((res) => {
                var geoJSON = res.data
                var coordinates = geoJSON.features
                if (coordinates.length > 0) {
                    coordinates.forEach((v) => {
                        let polygonArr = v['geometry']['coordinates'][0]
                        // 创建纯文本标记
                        var text = new AMap.Text({
                            text: v['properties']['range_name'],
                            cursor: 'pointer',
                            position: getCenterPoint(polygonArr),
                            zooms: [14, 18],
                            style: { 'background-color': 'transparent', border: 'none', fontSize: '11px', fontWeight: 'bold' }
                        })
                        var polygon = new AMap.Polygon({
                            path: polygonArr,
                            strokeColor: 'rgba(0,0,0,0.8)',
                            fillColor: 'rgba(0,0,200,0.4)'
                        })
                        map.value.add([polygon, text])
                    })
                }
            })
            //断面
            axios(
                'http://geo.jinhx.cn:8089/geoserver/marinfo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=marinfo:elec_range_duanmian&maxFeatures=50&outputFormat=application%2Fjson'
            ).then((res) => {
                var geoJSON = res.data
                // var area = new AMap.GeoJSON({
                //     geoJSON: geoJSON,
                //     // 还可以自定义getMarker和getPolyline
                //     getPolygon: function (geojson, lnglats) {
                //         return new AMap.Polygon({
                //             path: lnglats,
                //             strokeWeight: 1,
                //             strokeColor: 'rgba(0,0,0,0.8)',
                //             fillColor: 'rgba(0,255,255,0)'
                //         })
                //     }
                // })
                // map.value.add(area)
            })
            //电子围栏
            axios(
                'http://geo.jinhx.cn:8089/geoserver/marinfo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=marinfo:elec_range_enclosure&maxFeatures=50&outputFormat=application%2Fjson'
            ).then((res) => {
                var geoJSON = res.data
                var coordinates = geoJSON.features
                if (coordinates.length > 0) {
                    coordinates.forEach((v) => {
                        let polygonArr = v['geometry']['coordinates'][0]
                        // 创建纯文本标记
                        var text = new AMap.Text({
                            text: v['properties']['range_name'],
                            cursor: 'pointer',
                            position: getCenterPoint(polygonArr),
                            zooms: [14, 18],
                            style: { 'background-color': 'transparent', border: 'none', fontSize: '11px', fontWeight: 'bold' }
                        })
                        var polygon = new AMap.Polygon({
                            path: polygonArr,
                            strokeWeight: 2,
                            strokeColor: 'rgba(0,0,0,0.8)',
                            fillColor: 'rgba(153,255,255,0.6)'
                        })
                        map.value.add([text, polygon])
                    })
                }
            })
        }
        function svgPoints1(properties) {
            var style_url = `https://a.amap.com/jsapi_demos/static/images/mass1.png`,
                style_size = new AMap.Size(12, 12),
                style_anchor = new AMap.Pixel(6, 6)
            return {
                style_url,
                style_anchor,
                style_size
            }
        }
        /**船舶真实点位 */
        function svgPoints(properties: any, i?: number) {
            var fill = 'FFFF00',
                stroke = '000000',
                points = '',
                speed = properties['speed'],
                style_url = '',
                style_size = '',
                style_anchor = ''

            //填充色
            if (properties['isqdship'] == '1' || properties['code_name'] == '客渡船' || properties['code_name'] == '汽渡船') {
                fill = '#483D8B'
                stroke = '#000000'
            }
            switch (properties['data_type']) {
                case 'R':
                    //雷达信号点
                    fill = '#FFFF00'
                    break
                case 'G':
                    //本公司范围内的其他渡船颜色  紫色
                    fill = '#483D8B'
                    stroke = '#000000'
                    break

                default:
                    fill = '#FFFF00'
                    stroke = '#000000'
                    break
            }
            // 这个阶段用三角标识船舶
            if (map.value.getZoom() == 14 || map.value.getZoom() == 15) {
                width = 8
                length = 16
                //p1速度线
                if (properties['speed']) {
                    var s = properties['speed']
                    points = `4,0 4,${s} 8,${16 + s} 0,${16 + s} 4,${s}`
                    length = length + s
                } else {
                    s = 0
                    points = '4,0 8,16 0,16'
                }

                style_url =
                    'data:image/svg+xml;base64,' +
                    base64encode(
                        '<svg width="' +
                            width +
                            '" height="' +
                            length +
                            '" version="1.1" xmlns="http://www.w3.org/2000/svg">' +
                            '<polygon points="' +
                            points +
                            '" style="fill:' +
                            fill +
                            ';stroke:' +
                            stroke +
                            ';stroke-width:0.5" />' +
                            '</svg>'
                    )
                style_size = new AMap.Size(width, length)
                style_anchor = new AMap.Pixel(width / 2, (length / 2).toFixed(1))
            }
            //这个阶段展示真实尺寸船舶
            if (map.value.getZoom() > 15) {
                var resolution = map.value.getResolution()
                var width = properties['width'] || 15
                var length = properties['length'] || 40
                var widthPixel = Math.round(width / resolution)
                var lengthPixel = Math.round(length / resolution)
                var x = widthPixel,
                    y = lengthPixel
                var shipBodyPoints = [] as any[]
                //p1速度线
                if (properties['speed']) {
                    // var a = Math.round(properties['speed'] / resolution)
                    var s = speed
                    shipBodyPoints.push([x / 2, 0]) // p1 中
                } else {
                    s = 0
                }
                lengthPixel = y + s
                // 船体点包含(p2->p11,其中p2=p11)
                shipBodyPoints.push([x / 2, 0 + s]) // p2 中
                shipBodyPoints.push([0.2 * x + 1, 0.2 * y + s]) // p3 左
                shipBodyPoints.push([0 + 1, 0.4 * y + s]) // p4 左
                shipBodyPoints.push([0 + 1, 0.8 * y + s]) // p5 左
                shipBodyPoints.push([0.2 * x + 1, y + s - 1]) // p6 左
                shipBodyPoints.push([0.8 * x - 1, y + s - 1]) // p7 右
                shipBodyPoints.push([x - 1, 0.8 * y + s]) // p8 右
                shipBodyPoints.push([x - 1, 0.4 * y + s]) // p9 右
                shipBodyPoints.push([0.8 * x - 1, 0.2 * y + s]) // p10 右
                shipBodyPoints.push([x / 2, 0 + s]) // p11=p2 中
                points = points2String(shipBodyPoints)
                style_url =
                    'data:image/svg+xml;base64,' +
                    base64encode(
                        '<svg width="' +
                            widthPixel +
                            '" height="' +
                            lengthPixel +
                            '" version="1.1" xmlns="http://www.w3.org/2000/svg">' +
                            '<polygon points="' +
                            points +
                            '" style="fill:' +
                            fill +
                            ';stroke:' +
                            stroke +
                            ';stroke-width:0.5" />' +
                            '</svg>'
                    )
                style_size = new AMap.Size(widthPixel, lengthPixel)
                style_anchor = new AMap.Pixel(widthPixel / 2, (lengthPixel / 2).toFixed(1))
            }
            //雷达
            if (properties['data_type'] == 'R') {
                style_url = `https://a.amap.com/jsapi_demos/static/images/mass1.png`
                style_size = new AMap.Size(12, 12)
                style_anchor = new AMap.Pixel(6, 6)
            }

            // 显示底部label
            var labelMarker = new AMap.LabelMarker({
                name: properties['guid'],
                position: [properties['lng'], properties['lat']],
                zooms: [14, 20],
                opacity: 0.8,
                // zIndex: 1001,
                text: {
                    content: `${properties['cn_name'] || properties['ship_id']}|${parseFloat(properties['speed']).toFixed(2)}km/h`,
                    direction: 'bottom',
                    offset: [0, 10],
                    style: {
                        fontSize: 11,
                        fillColor: '#000',
                        strokeWeight: 0.5,
                        strokeColor: 'white'
                    }
                }
            })
            textlayer.add(labelMarker)
            map.value.add(textlayer)
            return {
                style_url,
                style_anchor,
                style_size
            }
        }
        /**svg array拼接 */
        function points2String(points) {
            var result = [] as number[]
            var point
            for (var i = 0; i < points.length; i++) {
                point = points[i]
                result.push(point.join(','))
            }
            return result.join(' ')
        }
        /**船舶定位展示 */
        async function showShipMarkers() {
            //120.90457118761273,31.770595701913727,120.9673134208891,31.778964194040192
            const {
                data: { features }
            } = await axios(
                'http://geo.jinhx.cn:8089/geoserver/marinfo/wfs?service=WFS&version=1.0.0&request=GetFeature&typename=marinfo:view_ship_blend&outputFormat=application/json&srsname=EPSG:4326' +
                    // '&bbox=120.90457118761273,31.770595701913727,120.9673134208891,31.778964194040192' +
                    '&t=' +
                    new Date().getTime()
            )
            textlayer.clear() //清除标注重绘
            const arr = [] as any
            const styles = [] as any
            if (features && features.length > 0) {
                features.forEach((v, i) => {
                    const { properties } = v
                    const { style_url, style_anchor, style_size } = svgPoints(properties, i) //分类型展示定位
                    arr.push({
                        speed: properties['speed'],
                        type: properties['data_type'],
                        width: properties['width'],
                        length: properties['length'],
                        lnglat: [properties['lng'], properties['lat']],
                        style: i,
                        extData: {
                            guid: properties['guid'],
                            content: `<div style="font-size:12px;"><div>船名：${properties['cn_name'] ? properties['cn_name'] : ''}</div><div>MMSI：${
                                properties['ship_id']
                            }</div>
                             <div>当前速度：${parseFloat(properties['speed']).toFixed(2)}km/h</div><div>更新时间：${properties['recive_time']
                                .substring(0, 19)
                                .replace(/T/, ' ')}</div>${properties['width']}||${properties['length']}</div>`
                        }
                    })
                    styles.push({
                        url: style_url,
                        anchor: style_anchor,
                        size: style_size,
                        rotation: properties['turn_rate']
                    })
                })
            }
            if (map.value.getZoom() < 14) {
                //红色圆点展示
                const style = {
                    url: 'https://a.amap.com/jsapi_demos/static/images/mass0.png',
                    anchor: new AMap.Pixel(6, 6),
                    size: new AMap.Size(11, 11)
                }
                state.MassMarksLayer.setStyle(style)
            } else {
                // 常规虚拟船舶点展示
                state.MassMarksLayer.setStyle(styles)
            }
            state.curStyle = styles
            state.curData = features
            state.MassMarksLayer.setData(arr)
            state.MassMarksLayer.setMap(map.value)
            state.MassMarksLayer.on('mouseover', showInfoOver)
        }
        /**轮询展示 */
        function showShips() {
            showShipMarkers()
            timer.value = setInterval(showShipMarkers, time)
        }
        /**信息窗体 */
        function showInfoOver(e) {
            const position = e.data.lnglat
            const speed = e.data.speed
            infoWindow.setContent(e.data.extData.content)
            infoWindow.open(map.value, [position['lng'], position['lat']])
            // 船舶围栏
            let resolution = map.value.getResolution()
            let radius = 0
            if (e.data.type == 'R') {
                radius = 8
            } else {
                if (map.value.getZoom() > 15) {
                    let ll = e.data.length || 40
                    let lengthPx = Math.round(ll / resolution)
                    radius = (lengthPx + speed) / 2 + 2
                } else {
                    radius = (16 + speed) / 2 + 2
                }
            }
            // console.log('radius',radius)
            circleMarker.setRadius(radius)
            circleMarker.setCenter([position['lng'], position['lat']])
            circleMarker.show()
        }
        function showInfoOut() {
            infoWindow.close()
            circleMarker.hide()
        }
        /**地图控件 */
        function addController() {
            map.value.plugin(['AMap.Scale', 'AMap.ToolBar', 'AMap.ControlBar'], function () {
                var scale = new AMap.Scale()
                var toolBar = new AMap.ToolBar()
                var controlBar = new AMap.ControlBar()
                map.value.addControl(scale)
                map.value.addControl(toolBar)
                map.value.addControl(controlBar)
            })
            //添加聚合组件
            // map.value.plugin(['AMap.MarkerClusterer'], function () {
            //     var cluster = new AMap.MarkerClusterer(
            //         map.value // 地图实例
            //         // points // 海量点数据，数据中需包含经纬度信息字段 lnglat
            //     )
            // })
            // 测量两点间长度控件【报错】
            // map.value.plugin(['AMap.RangingTool'], function () {
            //     var tool = new AMap.RangingTool(map.value)
            //     tool.turnOn()
            // })
        }
        /**地图事件 */
        function mapEvent() {
            //地图加载完成事件
            map.value.on('complete', function () {
                message.success('地图图块加载完毕！当前地图中心点为：' + map.value.getCenter())
            })
            //地图点击事件
            map.value.on('click', showInfoClick)
            function showInfoClick(e) {
                var text = '您在 [ ' + e.lnglat.getLng() + ',' + e.lnglat.getLat() + ' ] 的位置单击了地图！'
                message.success(text)
                showInfoOut()
            }
            //地图缩放事件
            map.value.on('zoomchange', mapZoom)
            // map.value.on('zoomchange', throttle(mapZoom, 300))
            function mapZoom() {
                var zoom = map.value.getZoom() //获取当前地图级别
                message.success('当前级别:' + zoom)
                if (zoom < 14) {
                    const style = {
                        url: 'https://a.amap.com/jsapi_demos/static/images/mass0.png',
                        anchor: new AMap.Pixel(6, 6),
                        size: new AMap.Size(11, 11)
                    }
                    state.MassMarksLayer.setStyle(style)
                } else {
                    // 常规虚拟船舶点展示
                    const styles = [] as any
                    state.curData.forEach((v) => {
                        const { properties } = v
                        const { style_url, style_anchor, style_size } = svgPoints(properties)
                        styles.push({
                            url: style_url,
                            anchor: style_anchor,
                            size: style_size,
                            rotation: properties['turn_rate']
                        })
                    })
                    state.MassMarksLayer.setStyle(styles)
                }
                // marker.on('click', showInfoM)
                function showInfoM(e) {
                    var text = '您在 [ ' + e.lnglat.getLng() + ',' + e.lnglat.getLat() + ' ] 的位置点击了marker！'
                    message.success(text)
                }
            }
        }
        /**
         * 获得图形的中心点
         */
        function getCenterPoint(path) {
            var lng = 0.0,
                lat = 0.0
            for (var i = 0; i < path.length; i++) {
                lng = lng + parseFloat(path[i][0])
                lat = lat + parseFloat(path[i][1])
            }
            lng = lng / path.length
            lat = lat / path.length
            return [lng, lat]
        }
        return {
            ...toRefs(state),
            defaultLayer,
            haituLayer,
            imageLayer
        }
        function drawPolygon() {
            var polygonArr = new Array() //多边形覆盖物节点坐标数组
            polygonArr.push([119.849207, 32.271868])
            polygonArr.push([119.85091, 32.270464])
            polygonArr.push([119.849389, 32.269609])
            polygonArr.push([119.847693, 32.271229])
            var text = new AMap.Text({
                text: 'sssssssssssssssssssssssssssss',
                cursor: 'pointer',
                position: getCenterPoint(polygonArr),
                zooms: [14, 18],
                style: { 'background-color': 'transparent', border: 'none', fontSize: '11px', fontWeight: 'bold' }
            })
            var polygon = new AMap.Polygon({
                path: polygonArr,
                strokeColor: 'rgba(0,0,0,0.8)',
                fillColor: 'rgba(0,0,200,0.4)'
            })
            map.value.add([polygon, text])
            var overlayGroup = new AMap.OverlayGroup([polygon, text])
            map.value.add(overlayGroup)
        }
    }
})
</script>

<style lang="scss" scoped>
@import 'https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css';
// @import 'https://cache.amap.com/lbs/static/main1119.css';
#container {
    height: 100%;
    width: 100%;
}
.input-card {
    bottom: 20rem !important;
}
#panel {
    position: absolute;
    background-color: white;
    max-height: 90%;
    overflow-y: auto;
    top: 10px;
    right: 10px;
    width: 280px;
    z-index: 999;
}
</style>
